home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 4 / QRZ Ham Radio Callsign Database - Volume 4.iso / files / dsp / 56ktools / dspkgctr.z / dspkgctr / gcc / config / tm-news800.h < prev    next >
C/C++ Source or Header  |  1992-06-08  |  13KB  |  372 lines

  1. /* Definitions of target machine for GNU compiler.  SONY NEWS version.
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GNU CC.
  5.  
  6. GNU CC is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GNU CC is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GNU CC; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /* Use the GNU Assembler, because the system's assembler
  21.    has no way to assemble the difference of two labels
  22.    for the displacement in a switch-dispatch instruction.  */
  23.  
  24. #define USE_GAS
  25.  
  26. #ifndef USE_GAS
  27. /* This controls conditionals in tm-m68k.h.  */
  28. #define MOTOROLA
  29. #endif
  30.  
  31. #include "tm-m68k.h"
  32.  
  33. /* See tm-m68k.h.  7 means 68020 with 68881.  */
  34.  
  35. #define TARGET_DEFAULT 7
  36.  
  37. /* Define __HAVE_68881__ in preprocessor, unless -msoft-float is specified.
  38.    This will control the use of inline 68881 insns in certain macros.  */
  39.  
  40. #define CPP_SPEC "%{!msoft-float:-D__HAVE_68881__}"
  41.  
  42. /* Names to predefine in the preprocessor for this target machine.  */
  43.  
  44. #define CPP_PREDEFINES "-Dunix -Dmc68020 -Dnews800 -Dsony -Dsony_news"
  45.  
  46. /* This is BSD, so it wants DBX format.  */
  47.  
  48. #define DBX_DEBUGGING_INFO
  49.  
  50. /* Override parts of tm-m68k.h to fit Sony's assembler syntax.  */
  51.  
  52. #undef POINTER_BOUNDARY
  53. #undef BIGGEST_ALIGNMENT
  54. #undef CALL_USED_REGISTERS
  55. #undef FUNCTION_VALUE
  56. #undef LIBCALL_VALUE
  57. #undef FUNCTION_PROFILER
  58.  
  59. #ifdef MOTOROLA
  60. #undef FUNCTION_PROLOGUE
  61. #undef FUNCTION_EPILOGUE
  62. #undef REGISTER_NAMES
  63. #undef ASM_OUTPUT_REG_PUSH
  64. #undef ASM_OUTPUT_REG_POP
  65. #undef ASM_OUTPUT_DOUBLE
  66. #undef ASM_OUTPUT_SKIP
  67. #undef PRINT_OPERAND
  68. #undef PRINT_OPERAND_ADDRESS
  69. #endif  
  70.  
  71. #undef ASM_OUTPUT_ALIGN
  72.  
  73. /* Allocation boundary (in *bits*) for storing pointers in memory.  */
  74. #define POINTER_BOUNDARY 32
  75.  
  76. /* There is no point aligning anything to a rounder boundary than this.  */
  77. #define BIGGEST_ALIGNMENT 32
  78.  
  79. /* A bitfield declared as `int' forces `int' alignment for the struct.  */
  80. #define PCC_BITFIELD_TYPE_MATTERS
  81.   
  82. /* NEWS makes d2, d3, fp2 and fp3 unsaved registers, unlike the Sun system.  */
  83.   
  84. #define CALL_USED_REGISTERS \
  85.  {1, 1, 1, 1, 0, 0, 0, 0, \
  86.   1, 1, 0, 0, 0, 0, 0, 1, \
  87.   1, 1, 1, 1, 0, 0, 0, 0}
  88.  
  89. /* NEWS returns floats and doubles in fp0, not d0/d1.  */
  90.  
  91. #define FUNCTION_VALUE(VALTYPE,FUNC) LIBCALL_VALUE (TYPE_MODE (VALTYPE))
  92.  
  93. #define LIBCALL_VALUE(MODE) \
  94.  gen_rtx (REG, (MODE), ((TARGET_68881 && ((MODE) == SFmode || (MODE) == DFmode)) ? 16 : 0))
  95.  
  96. #define ASM_OUTPUT_ALIGN(FILE,LOG)    \
  97.   fprintf (FILE, "\t.align %d\n", (LOG))
  98.  
  99. #ifdef MOTOROLA
  100.  
  101. #define FUNCTION_PROLOGUE(FILE, SIZE)     \
  102. { register int regno;                        \
  103.   register int mask = 0;                    \
  104.   static char *reg_names[] = REGISTER_NAMES;            \
  105.   extern char call_used_regs[];                    \
  106.   int fsize = (SIZE);                        \
  107.   if (frame_pointer_needed)                    \
  108.     { if (TARGET_68020 || fsize < 0x10000)            \
  109.         fprintf (FILE, "\tlink fp,#%d\n", -fsize);        \
  110.       else                            \
  111.     fprintf (FILE, "\tlink fp,#0\n\tsub.l #%d,sp\n", fsize); }  \
  112.   for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)    \
  113.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  114.        mask |= 1 << (regno - 16);                \
  115.   if (mask != 0)                        \
  116.     fprintf (FILE, "\tfmovem.x #0x%x,-(sp)\n", mask & 0xff);    \
  117.   mask = 0;                            \
  118.   for (regno = 0; regno < 16; regno++)                \
  119.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  120.        mask |= 1 << (15 - regno);                \
  121.   if (frame_pointer_needed)                    \
  122.     mask &= ~ (1 << (15-FRAME_POINTER_REGNUM));            \
  123.   if (exact_log2 (mask) >= 0)                    \
  124.     fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[15 - exact_log2 (mask)]);  \
  125.   else if (mask) fprintf (FILE, "\tmovem.l #0x%x,-(sp)\n", mask); }
  126.  
  127. #define FUNCTION_PROFILER(FILE, LABEL_NO) \
  128.    fprintf (FILE, "\tmove.l #LP%d,d0\n\tjsr mcount\n", (LABEL_NO));
  129.  
  130. #define FUNCTION_EPILOGUE(FILE, SIZE) \
  131. { register int regno;                        \
  132.   register int mask, fmask;                    \
  133.   register int nregs;                        \
  134.   int offset, foffset;                        \
  135.   extern char call_used_regs[];                    \
  136.   static char *reg_names[] = REGISTER_NAMES;            \
  137.   extern int current_function_pops_args;            \
  138.   extern int current_function_args_size;            \
  139.   int fsize = (SIZE);                        \
  140.   int big = 0;                            \
  141.   nregs = 0;  fmask = 0;                    \
  142.   for (regno = 16; regno < FIRST_PSEUDO_REGISTER; regno++)    \
  143.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  144.       { nregs++; fmask |= 1 << (23 - regno); }            \
  145.   foffset = nregs * 12;                        \
  146.   nregs = 0;  mask = 0;                        \
  147.   if (frame_pointer_needed) regs_ever_live[FRAME_POINTER_REGNUM] = 0; \
  148.   for (regno = 0; regno < 16; regno++)                \
  149.     if (regs_ever_live[regno] && ! call_used_regs[regno])    \
  150.       { nregs++; mask |= 1 << regno; }                \
  151.   offset = foffset + nregs * 4;                    \
  152.   if (offset + fsize >= 0x8000 && frame_pointer_needed)        \
  153.     { fprintf (FILE, "\tmove.l #%d,a0\n", -fsize);        \
  154.       fsize = 0, big = 1; }                    \
  155.   if (exact_log2 (mask) >= 0) {                    \
  156.     if (big)                            \
  157.       fprintf (FILE, "\tmove.l (-%d,fp,a0.l),%s\n",        \
  158.            offset + fsize, reg_names[exact_log2 (mask)]);    \
  159.     else if (! frame_pointer_needed)                \
  160.       fprintf (FILE, "\tmove.l (sp)+,%s\n",            \
  161.            reg_names[exact_log2 (mask)]);            \
  162.     else                            \
  163.       fprintf (FILE, "\tmove.l (-%d,fp),%s\n",            \
  164.            offset + fsize, reg_names[exact_log2 (mask)]); }    \
  165.   else if (mask) {                        \
  166.     if (big)                            \
  167.       fprintf (FILE, "\tmovem.l (-%d,fp,a0.l),#0x%x\n",        \
  168.            offset + fsize, mask);                \
  169.     else if (! frame_pointer_needed)                \
  170.       fprintf (FILE, "\tmovem.l (sp)+,#0x%x\n", mask);        \
  171.     else                            \
  172.       fprintf (FILE, "\tmovem.l (-%d,fp),#0x%x\n",        \
  173.            offset + fsize, mask); }                \
  174.   if (fmask) {                            \
  175.     if (big)                            \
  176.       fprintf (FILE, "\tfmovem.x (-%d,fp,a0.l),#0x%x\n",    \
  177.            foffset + fsize, fmask);                \
  178.     else if (! frame_pointer_needed)                \
  179.       fprintf (FILE, "\tfmovem.x (sp)+,#0x%x\n", fmask);    \
  180.     else                            \
  181.       fprintf (FILE, "\tfmovem.x (-%d,fp),#0x%x\n",        \
  182.            foffset + fsize, fmask); }            \
  183.   if (frame_pointer_needed)                    \
  184.     fprintf (FILE, "\tunlk fp\n");                \
  185.   if (current_function_pops_args && current_function_args_size)    \
  186.     fprintf (FILE, "\trtd #%d\n", current_function_args_size);    \
  187.   else fprintf (FILE, "\trts\n"); }
  188.  
  189. /* Difference from tm-m68k.h is in `fp' instead of `a6'.  */
  190.  
  191. #define REGISTER_NAMES \
  192. {"d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",    \
  193.  "a0", "a1", "a2", "a3", "a4", "a5", "fp", "sp",    \
  194.  "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7"}
  195.  
  196. /* This is how to output an insn to push a register on the stack.
  197.    It need not be very fast code.  */
  198.  
  199. #define ASM_OUTPUT_REG_PUSH(FILE,REGNO)  \
  200.   fprintf (FILE, "\tmove.l %s,-(sp)\n", reg_names[REGNO])
  201.  
  202. /* This is how to output an insn to pop a register from the stack.
  203.    It need not be very fast code.  */
  204.  
  205. #define ASM_OUTPUT_REG_POP(FILE,REGNO)  \
  206.   fprintf (FILE, "\tmove.l (sp)+,%s\n", reg_names[REGNO])
  207.   
  208. #define ASM_OUTPUT_DOUBLE(FILE,VALUE)  \
  209.   fprintf (FILE, "\t.double 0d%.20e\n", (VALUE))
  210.  
  211. #define ASM_OUTPUT_SKIP(FILE,SIZE)  \
  212.   fprintf (FILE, "\t.space %d\n", (SIZE))
  213.  
  214. #define PRINT_OPERAND(FILE, X, CODE)  \
  215. { if (CODE == '.') fprintf (FILE, ".");                    \
  216.   else if (CODE == '#') fprintf (FILE, "#");                \
  217.   else if (CODE == '-') fprintf (FILE, "-(sp)");            \
  218.   else if (CODE == '+') fprintf (FILE, "(sp)+");            \
  219.   else if (CODE == 's') fprintf (FILE, "(sp)");                \
  220.   else if (CODE == '!') fprintf (FILE, "ccr");                \
  221.   else if (GET_CODE (X) == REG)                        \
  222.     fprintf (FILE, "%s", reg_name [REGNO (X)]);                \
  223.   else if (GET_CODE (X) == MEM)                        \
  224.     output_address (XEXP (X, 0));                    \
  225.   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) == SFmode)    \
  226.     { union { double d; int i[2]; } u;                    \
  227.       union { float f; int i; } u1;                    \
  228.       u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X);    \
  229.       u1.f = u.d;                            \
  230.       if (CODE == 'f')                            \
  231.         fprintf (FILE, "#0f%.9e", u1.f);                \
  232.       else                                \
  233.         fprintf (FILE, "#0x%x", u1.i); }                \
  234.   else if (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != DImode)    \
  235.     { union { double d; int i[2]; } u;                    \
  236.       u.i[0] = CONST_DOUBLE_LOW (X); u.i[1] = CONST_DOUBLE_HIGH (X);    \
  237.       fprintf (FILE, "#0d%.20e", u.d); }                \
  238.   else if (CODE == 'b') output_addr_const (FILE, X);            \
  239.   else { putc ('#', FILE); output_addr_const (FILE, X); }}
  240.  
  241. #define PRINT_OPERAND_ADDRESS(FILE, ADDR)  \
  242. { register rtx reg1, reg2, breg, ireg;                    \
  243.   register rtx addr = ADDR;                        \
  244.   rtx offset;                                \
  245.   switch (GET_CODE (addr))                        \
  246.     {                                    \
  247.     case REG:                                \
  248.       fprintf (FILE, "(%s)", reg_name [REGNO (addr)]);            \
  249.       break;                                \
  250.     case PRE_DEC:                            \
  251.       fprintf (FILE, "-(%s)", reg_name [REGNO (XEXP (addr, 0))]);    \
  252.       break;                                \
  253.     case POST_INC:                            \
  254.       fprintf (FILE, "(%s)+", reg_name [REGNO (XEXP (addr, 0))]);    \
  255.       break;                                \
  256.     case PLUS:                                \
  257.       reg1 = 0;    reg2 = 0;                        \
  258.       ireg = 0;    breg = 0;                        \
  259.       offset = 0;                            \
  260.       if (CONSTANT_ADDRESS_P (XEXP (addr, 0)))                \
  261.     {                                \
  262.       offset = XEXP (addr, 0);                    \
  263.       addr = XEXP (addr, 1);                    \
  264.     }                                \
  265.       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1)))            \
  266.     {                                \
  267.       offset = XEXP (addr, 1);                    \
  268.       addr = XEXP (addr, 0);                    \
  269.     }                                \
  270.       if (GET_CODE (addr) != PLUS) ;                    \
  271.       else if (GET_CODE (XEXP (addr, 0)) == SIGN_EXTEND)        \
  272.     {                                \
  273.       reg1 = XEXP (addr, 0);                    \
  274.       addr = XEXP (addr, 1);                    \
  275.     }                                \
  276.       else if (GET_CODE (XEXP (addr, 1)) == SIGN_EXTEND)        \
  277.     {                                \
  278.       reg1 = XEXP (addr, 1);                    \
  279.       addr = XEXP (addr, 0);                    \
  280.     }                                \
  281.       else if (GET_CODE (XEXP (addr, 0)) == MULT)            \
  282.     {                                \
  283.       reg1 = XEXP (addr, 0);                    \
  284.       addr = XEXP (addr, 1);                    \
  285.     }                                \
  286.       else if (GET_CODE (XEXP (addr, 1)) == MULT)            \
  287.     {                                \
  288.       reg1 = XEXP (addr, 1);                    \
  289.       addr = XEXP (addr, 0);                    \
  290.     }                                \
  291.       else if (GET_CODE (XEXP (addr, 0)) == REG)            \
  292.     {                                \
  293.       reg1 = XEXP (addr, 0);                    \
  294.       addr = XEXP (addr, 1);                    \
  295.     }                                \
  296.       else if (GET_CODE (XEXP (addr, 1)) == REG)            \
  297.     {                                \
  298.       reg1 = XEXP (addr, 1);                    \
  299.       addr = XEXP (addr, 0);                    \
  300.     }                                \
  301.       if (GET_CODE (addr) == REG || GET_CODE (addr) == MULT        \
  302.       || GET_CODE (addr) == SIGN_EXTEND)                \
  303.     { if (reg1 == 0) reg1 = addr; else reg2 = addr; addr = 0; }    \
  304.       if (offset != 0) { if (addr != 0) abort (); addr = offset; }    \
  305.       if ((reg1 && (GET_CODE (reg1) == SIGN_EXTEND            \
  306.             || GET_CODE (reg1) == MULT))            \
  307.       || (reg2 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg2))))        \
  308.     { breg = reg2; ireg = reg1; }                    \
  309.       else if (reg1 != 0 && REGNO_OK_FOR_BASE_P (REGNO (reg1)))        \
  310.     { breg = reg1; ireg = reg2; }                    \
  311.       if (ireg != 0 && breg == 0 && GET_CODE (addr) == LABEL_REF)    \
  312.         { int scale = 1;                        \
  313.       if (GET_CODE (ireg) == MULT)                    \
  314.         { scale = INTVAL (XEXP (ireg, 1));                \
  315.           ireg = XEXP (ireg, 0); }                    \
  316.       if (GET_CODE (ireg) == SIGN_EXTEND)                \
  317.         fprintf (FILE, "(L%d-LI%d.b,pc,%s.w",            \
  318.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  319.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  320.              reg_name[REGNO (XEXP (ireg, 0))]);         \
  321.       else                                \
  322.         fprintf (FILE, "(L%d-LI%d.b,pc,%s.l",            \
  323.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  324.              CODE_LABEL_NUMBER (XEXP (addr, 0)),        \
  325.              reg_name[REGNO (ireg)]);                \
  326.       if (scale != 1) fprintf (FILE, "*%d", scale);            \
  327.       putc (')', FILE);                        \
  328.       break; }                            \
  329.       if (ireg != 0 || breg != 0)                    \
  330.     { int scale = 1;                        \
  331.       if (breg == 0)                        \
  332.         abort ();                            \
  333.       fprintf (FILE, "(");                        \
  334.       if (addr != 0) {                        \
  335.         output_addr_const (FILE, addr);                \
  336.         putc (',', FILE); }                        \
  337.       fprintf (FILE, "%s", reg_name[REGNO (breg)]);            \
  338.       if (ireg != 0)                        \
  339.         putc (',', FILE);                        \
  340.       if (ireg != 0 && GET_CODE (ireg) == MULT)            \
  341.         { scale = INTVAL (XEXP (ireg, 1));                \
  342.           ireg = XEXP (ireg, 0); }                    \
  343.       if (ireg != 0 && GET_CODE (ireg) == SIGN_EXTEND)        \
  344.         fprintf (FILE, "%s.w", reg_name[REGNO (XEXP (ireg, 0))]);    \
  345.       else if (ireg != 0)                        \
  346.         fprintf (FILE, "%s.l", reg_name[REGNO (ireg)]);        \
  347.       if (scale != 1) fprintf (FILE, "*%d", scale);            \
  348.       putc (')', FILE);                        \
  349.       break;                            \
  350.     }                                \
  351.       else if (reg1 != 0 && GET_CODE (addr) == LABEL_REF)        \
  352.     { fprintf (FILE, "(L%d-LI%d.b,pc,%s:l)",            \
  353.            CODE_LABEL_NUMBER (XEXP (addr, 0)),            \
  354.            CODE_LABEL_NUMBER (XEXP (addr, 0)),            \
  355.            reg_name[REGNO (reg1)]);                \
  356.       break; }                            \
  357.     default:                                \
  358.       if (GET_CODE (addr) == CONST_INT                    \
  359.       && INTVAL (addr) < 0x8000                    \
  360.       && INTVAL (addr) >= -0x8000)                    \
  361.     fprintf (FILE, "%d.w", INTVAL (addr));                \
  362.       else                                \
  363.         output_addr_const (FILE, addr);                    \
  364.     }}
  365.  
  366. #else /* Using GAS, which uses the MIT assembler syntax, like a Sun.  */
  367.  
  368. #define FUNCTION_PROFILER(FILE, LABEL_NO) \
  369.    fprintf (FILE, "\tmovl #LP%d,d0\n\tjsr mcount\n", (LABEL_NO));
  370.  
  371. #endif /* MOTOROLA */
  372.